import React from 'react';
import './-page.scss';
import {observable, observer, action, autorun} from 'mobx.collection';
import {formatClassList} from "auxiliaries/extends/format";
import {Link} from "react-router-dom";

@observer
class ListMenuDap extends React.Component {
    @observable ListItem = [];
    @observable DisplayState = [];
    @observable NewChildren;
    @observable CurrentIndex;
    @observable CurrentActiveIndexList = [];
    DisplayBackState = [];

    componentDidMount() {
        this.CurrentActiveIndexList = React.Children.toArray(this.props.children).filter(Boolean).map(x => {
            return x.props['currentActiveIndex'] || '';
        }).map(x => x === '' ? undefined : x);
        this.DisplayState = React.Children.toArray(this.props.children)?.map(() => false);
        this.updateChildren();
    }

    #DisplayDisposer = autorun(() => {
        if (typeof this.CurrentIndex === 'number' && typeof this.DisplayState[this.CurrentIndex] === 'boolean') {
            this.updateChildren(this.props);
        }
    });

    componentWillUnmount() {
        this.#DisplayDisposer();
    }

    @action
    updateChildren(props) {
        let {
            children
        } = props || this.props;

        this.NewChildren = React.Children.toArray(children).filter(Boolean).map((x, index) => {
            let props = {
                ...x.props,
                index,
                '--onClick': x.props?.onClick
            };

            props.displayState = this.DisplayState[index];
            props.onClick = () => this.onClick(props);
            return React.cloneElement(x, props);
        });
    }

    componentWillReceiveProps(nextProps) {
        this.updateChildren(nextProps);
        React.Children.toArray(nextProps.children).filter(Boolean).forEach(({props}, index) => {
            if (this.DisplayBackState[index]) {
                this.DisplayBackState[index] = false;
                this.ListItem = props?.list.map(x => x?.Name || x?.name || `${x}`);
            }
        });
    }

    @action
    async onClick(props) {
        let {
            [['--onClick']]: clickEvent,
            onClick,
            ...rest
        } = props;
        let {
            index
        } = rest;
        this.DisplayBackState[index] = true;
        let ok = await clickEvent?.(rest);
        if (typeof ok === 'boolean' && !ok) {
            return;
        }

        if (this.DisplayState[index]) {
            this.DisplayState[index] = false;
            return;
        }


        if (this.DisplayBackState[index]) {
            this.ListItem = props?.list?.map(x => x?.Name || x?.name || `${x}`) || [];
        }

        this.CurrentIndex = index;
        // this.DisplayState = ' '.repeat(index + 1).split(' ').map((_, i) => i === index);
        // this.DisplayState[index] = true;
        this.DisplayBackState = this.DisplayBackState.map(x => false);
        this.DisplayState.forEach((_, i) => this.DisplayState[i] = (i === index));
        this.DisplayBackState[index] = true;
    }

    onContainerClick(e) {
        if (e.clientY < (window.innerHeight / 1.5)) {
            this.DisplayState = this.DisplayState.map(() => false);
        }
    }

    async onItemClick(name, index) {
        let {
            onItemClick
        } = this.props;
        let currentSelectResult = this.CurrentActiveIndexList[this.CurrentIndex];

        if (currentSelectResult === index) {
            currentSelectResult = null;
        } else {
            currentSelectResult = index;
        }

        let ok = await onItemClick?.(name, index, currentSelectResult, this.CurrentIndex);

        this.CurrentActiveIndexList[this.CurrentIndex] = currentSelectResult;

        if (typeof ok === 'boolean' && !ok) {
            return;
        }

        this.DisplayState[this.CurrentIndex] = false;
    }

    render() {
        let {
            className,
        } = this.props;

        return (
            <div className={[
                "--list-menu-dap",
                "flex-start"
            ].concat(formatClassList(className)).join(' ')}>
                {this.NewChildren}
                <div className={"--list-container" + (this.DisplayState.indexOf(true) >= 0 ? ' on' : '')}
                     onClick={_ => this.onContainerClick(_)}>
                    <div className="--list-space">
                        <div className="--list-group">
                            {
                                this.ListItem.map((x, key) => (
                                    <div className={"--list-item font-size-34 touch-active" +
                                    (this.CurrentActiveIndexList[this.CurrentIndex] === key ? ' on' : '')}
                                         key={x + key}
                                         onClick={() => this.onItemClick(x, key)}>
                                        {x}
                                    </div>
                                ))
                            }
                        </div>
                    </div>
                </div>
            </div>
        );
    }
}

@observer
class ListMenuItem extends React.Component {
    onLinkBefore(e) {
        this.props.onLinkBeforeCLick?.(e);
    }
    
    onClick(e) {
        let {
            to,
            onClick,
        } = this.props;


        if (!to) {
            onClick?.();
        }
    }

    render() {
        let {
            title,
            icoClassName,
            className,
            displayState,
            activeClass = '',
            to
        } = this.props;

        //todo: 优化：由于父级displayState的变更导致所有子组件都发生了变化。
        let classResult = "touch-active --list-menu-item flex-start" +
            (className ? ` ${className}` : '') +
            (displayState && activeClass ? ` ${activeClass}` : '');
        let all = <>
            <span className={"ico" + (icoClassName ? ` ${icoClassName}` : icoClassName)}/>
            <span>{title}</span>
        </>;
        return (
            to ?
                <Link to={to} className={classResult} onClick={this.onLinkBefore.bind(this)}>
                    {all}
                </Link>
                :
                <div className={classResult}
                     onClick={this.onClick.bind(this)}>
                    {all}
                </div>
        );
    }
}

export {
    ListMenuDap,
    ListMenuItem
};